#if _MSC_VER
 #pragma once
#endif

#ifndef __APPUTIL_AIR_INCLUDED__
 #define __APPUTIL_AIR_INCLUDED__
 #include "AppUtilPrecompiled.hxx"
 #include "AppUtilAirTraits.hxx"

 #ifndef REIGN_DESKTOP
  #define __air_dectructor_access	private		// Public non-virtual dtors are not allowed. 
 #else 
  #define __air_dectructor_access	public		// The destructor should public otherwise friend types or functions should be specified. 
 #endif
 
 
HerzeleidLoggingNamespaceBegin ref_class_decl Air											// Provides a very basic functionaity for logging.
{
owned_access:

	typedef wchar_t Char;																// Represents a single message element
	typedef std::wstring Message;															// Represents the message that will be displayed. 
	typedef std::exception StandardError;												// Represents a standard exception.
	typedef concurrency::task<bool> AsyncAction;										// Represents an asynchronous cancellable action.
	typedef Microsoft::WRL::Wrappers::FileHandle FileHandle;							// Represents a basic file handle. 
	typedef concurrency::task_canceled AsyncActionCanceledError;						// Represents an asynchronous task cancelled exception.
	typedef concurrency::cancellation_token AsyncCancellationToken;						// Represents an asynchronous cancellation token.
	typedef concurrency::cancellation_token_source AsyncCancellationTokenSource;		// Represents an asynchronous cancellation token source.
	typedef Concurrency::concurrent_queue<Message> MessageQueue;						// Represents a message queue
	TinyTypeDecl( AsyncActionCanceledError );											// Represents an asynchronous task cancelled exception.
	TinyTypeDecl( StandardError );														// Represents a standard exception.
	TinyTypeDecl( MessageQueue );														// Captured message queue
	TinyTypeDecl( Message );															// Window message raw description

	MessageQueue m_MessageQueue;														// Message storage. 
	FileHandle m_FileWriteHandle;														// File handle for write only access. 
	AsyncCancellationTokenSource m_PrintingCancellationSrc;								// Cancellation token source for printing routine. 
	AsyncCancellationTokenSource m_CapturingCancellationSrc;							// Cancellation token source for capturing routine. 
	AsyncAction m_MessageCapturing;														// Message capturing routine. 
	AsyncAction m_MessagePrinting;														// Message printing routine. 

__air_dectructor_access:

	// Releases logger instance and waits until all the messages are displayed (COMMON). 
	~Air();

public_owned_access:

	// Creates logger instance (COMMON). 
	Air();

#ifndef REIGN_DESKTOP
	// Appends message to the message storage to print it later.
	// REMARKS: Metro and Phone only. 
	void Grab( _In_z_ Platform::String^ MessageString );
#else // Variadic functions are not allowed in ref classes. 
	// Appends message to the message storage to print it later. 
	// REMARKS: Desktop specific. Max = 260 symbols (MAX_PATH). 
	void GrabWithArgs(  
		_Printf_format_string_ Char const *wszFormat, // Message format
		_Printf_format_string_params_(ppArgs) ... // Message args
		);
#endif

	// Appends message to the message storage to print it later (COMMON). 
	void Grab( _In_z_ Message wszMessage );
	// Starts/extends printing task chain according to the provided option (COMMON). 
	void Print( _In_ AirTraits::AirPrintMessagesOption eOption );
	// Waits until the task chains are completed. All the unprinted messages will be printed w/o any delaying.
	// This function will be executed when destroying the logger instance (COMMON). 
	void Await( );
	// Cancels both message capturing and printing task chains. All the unprinted messages will be discarded (COMMON). 
	void Cancel( );

owned_access:

	// Prints the message immediately (INTERNAL/COMMON). 
	Int32 PrintNext();
	// Print the message with delay (or not) (INTERNAL/COMMON). 
	void PrintNextAsync();
	// Restarts all the task chains (after they were cancelled as usual) (INTERNAL/COMMON). 
	void Restart();

} HerzeleidLoggingNamespaceEnd; 

#ifndef REIGN_DESKTOP
 #undef __air_dectructor_access 
#else
 #undef __air_dectructor_access  
#endif

#endif // !HERZELEID_AIR_INCLUDED__
